home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d882.lha / GALer / GALer_english / Source / GALerSrcE.lha / Optimizer.c < prev    next >
C/C++ Source or Header  |  1992-12-26  |  41KB  |  1,493 lines

  1. /****************************************************************/
  2. /*                                */
  3. /* Optimizer.c - dieses Modul enthält den Optimierer für    */
  4. /*         die Booleschen Ausdrücke            */
  5. /*                                */
  6. /* Funktionsweise des Optimierers:                */
  7. /* Zunächst wird das normale Source-File "name.pld" geladen    */
  8. /* und bis zu den Gleichungen so ausgewertet als ob es assem-    */
  9. /* bliert werden soll. Das heißt: Bei Verstößen gegen die    */
  10. /* Syntax wird abgebrochen.                    */
  11. /* Wenn bis dahin kein Fehler aufgetreten ist, werden die    */
  12. /* Gleichungen codiert (Zahlen anstatt Strings) in den Speicher */
  13. /* abgelegt. Wenn dabei kein Fehler auftrat, wird mit Hilfe    */
  14. /* des Quine-McCluskey - Algorithmus versucht, die Gleichungen    */
  15. /* zu vereinfachen.                        */
  16. /* Zum Schluß werden die codierten (und vereinfachten) Gleich-    */
  17. /* ungen wieder in Textform zurückgewandelt und abgespeichert.    */
  18. /*                                */
  19. /*                                */
  20. /* compilieren: cc Optimizer.c                    */
  21. /*                                */
  22. /****************************************************************/
  23.  
  24.  
  25. #include <exec/memory.h>
  26. #include <libraries/dos.h>
  27. #include <intuition/intuition.h>
  28. #include <functions.h>
  29. #include <stdio.h>
  30.  
  31. #include "GALer.h"
  32.  
  33.  
  34. #define    TAKEIT_GADID    1
  35. #define FORGETIT_GADID    2
  36. #define WEITER_GADID    10
  37.  
  38.  
  39.  
  40. extern    int    num_of_pins, asmreadyflag, gal_type, num_of_col;
  41. extern    LONG    fsize;
  42. extern    UBYTE    *fbuff;
  43. extern    UBYTE    *actptr, *buffend;
  44. extern    UBYTE    PinNamesOpt[24][10];
  45. extern    char    path[];
  46.  
  47.  
  48. extern    struct    Pin        actPin;
  49. extern    struct    Screen        *screen;
  50. extern    struct    Window        *window;
  51. extern    struct    Menu        Menu1;
  52.  
  53. struct    RastPort    *orp;        /*RastPort für Optimizer-Window*/
  54. struct    Window        *optwin;
  55.  
  56.  
  57. UBYTE    OptTxt1[]    = "optimized equation   xxxx:";
  58.  
  59.  
  60. int    oypos, scrolls, reqflag;
  61. int    num_of_ORs, num_of_ANDs;
  62. int    numofpins_Opt;
  63.                 /*oypos: y-Pos. für Text im Optimizer-Window*/
  64.                 /*scrolls: wie oft gescrollt wurde*/
  65.                 /*reqflag: Scrollreq. ja oder nein ?*/
  66.  
  67.  
  68.  
  69.  
  70. SHORT OBorderVectors1a[] = { 0,12,96,12,96,0 };
  71. SHORT OBorderVectors1b[] = { 0,12,0,0,96,0 };
  72.  
  73. SHORT OBorderVectors2a[] = { 0,47,344,47,344,0 };
  74. SHORT OBorderVectors2b[] = { 0,47,0,0,344,0 };
  75.  
  76. SHORT OBorderVectors3a[] = { 0,12,96,12,96,0 };
  77. SHORT OBorderVectors3b[] = { 0,12,0,0,96,0 };
  78.  
  79. SHORT OBorderVectors4a[] = { 0,12,73,12,73,0 };
  80. SHORT OBorderVectors4b[] = { 0,12,0,0,73,0 };
  81.  
  82. SHORT SRBorVeca[]     = { 0,59,349,59,349,0 };
  83. SHORT SRBorVecb[]     = { 0,59,0,0,349,0 };
  84.  
  85.  
  86. struct Border OBorder1b  = { -1,-1,2,0,JAM1,3,OBorderVectors1b,NULL };
  87. struct Border OBorder1a  = { -1,-1,1,0,JAM1,3,OBorderVectors1a,&OBorder1b };
  88.  
  89. struct Border OBorder2b  = { -1,-1,2,0,JAM1,3,OBorderVectors2b,NULL };
  90. struct Border OBorder2a  = { -1,-1,1,0,JAM1,3,OBorderVectors2a,&OBorder2b };
  91.  
  92. struct Border OBorder3b  = { -1,-1,2,0,JAM1,5,OBorderVectors3b,NULL };
  93. struct Border OBorder3a  = { -1,-1,1,0,JAM1,5,OBorderVectors3a,&OBorder3b };
  94.  
  95. struct Border OBorder4b  = { -1,-1,2,0,JAM1,3,OBorderVectors4b,NULL };
  96. struct Border OBorder4a  = { -1,-1,1,0,JAM1,3,OBorderVectors4a,&OBorder4b };
  97.  
  98. struct Border SRBorderb  = { 0,0,2,0,JAM1,3,SRBorVecb,NULL };
  99. struct Border SRBordera  = { 0,0,1,0,JAM1,3,SRBorVeca,&SRBorderb };
  100.  
  101.  
  102.  
  103. struct IntuiText OIText1 = { 2,0,JAM2,12,2,NULL,
  104.                  (UBYTE *)" reject",NULL };
  105.  
  106. struct IntuiText OIText2 = { 2,0,JAM2,8,2,NULL,
  107.                 (UBYTE *)"  use it",NULL };
  108.  
  109. struct IntuiText OIText4 = { 2,0,JAM1,13,2,NULL,
  110.                 (UBYTE *)" Cont",NULL };
  111.  
  112. struct IntuiText OIText5 = { 2,0,JAM1,13,10,NULL,
  113.                 (UBYTE *)"press any key or select 'Cont'",
  114.                 NULL };
  115.  
  116. UBYTE  opttitle[] = "Optimizer";
  117.  
  118. struct Gadget OGadget3 = { NULL,521,169,95,11,NULL,
  119.                 RELVERIFY,
  120.                BOOLGADGET,
  121.                (APTR)&OBorder1a,
  122.                NULL,&OIText1,NULL,NULL,FORGETIT_GADID,NULL };
  123.  
  124. struct Gadget OGadget1 = { &OGadget3,389,169,95,11,NULL,
  125.                RELVERIFY,
  126.                BOOLGADGET,
  127.                (APTR)&OBorder1a,
  128.                NULL,&OIText2,NULL,NULL,TAKEIT_GADID,NULL };
  129.  
  130. struct Gadget OGadget2 = { NULL,138,38,72,11,
  131.                NULL,
  132.                RELVERIFY,
  133.                BOOLGADGET+REQGADGET,
  134.                (APTR)&OBorder4a,NULL,
  135.                &OIText4,NULL,NULL,WEITER_GADID,NULL };
  136.  
  137.  
  138. struct NewWindow OptWindow = { 0,0,640,200,0,1,
  139.                    GADGETUP+VANILLAKEY,
  140.                    WINDOWDEPTH+ACTIVATE+NOCAREREFRESH,
  141.                    &OGadget1,NULL,
  142.                    (UBYTE *)opttitle,
  143.                    NULL,NULL,5,5,-1,-1,
  144.                    CUSTOMSCREEN };
  145.  
  146.  
  147.  
  148. struct Requester ScrollReq = { NULL,150,138,350,60,0,0,
  149.                    &OGadget2,&SRBordera,&OIText5,
  150.                    NOISYREQ,3,NULL,NULL,NULL };
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157. /* Optimizer  -   Boolesche Gleichungen vereinfachen
  158.    Paramter: ---
  159.    Ergegnis:  0: alles o.k.   sonst: Fehler oder Abbruch
  160. */
  161. int Optimizer()
  162. {
  163. struct    IntuiMessage    *imsg;
  164. struct    ActBuffer    AllEquas, OptEqua, FileEquas;
  165. struct    Buffer        *FirstAllEquas, *FirstOptEqua, *FirstFileEquas;
  166. ULONG    class;
  167. USHORT    code, gadID;
  168. UBYTE    *equastart, *equaend;             /*Gleichungsanfang und -ende*/
  169. int    n, equaflag, asmreadyflag2, gal_type2, num_of_pins2, num_of_col2;
  170. char    statstrng[6];
  171.  
  172.                 /*AllEquas: Puffer in dem alle Gleichungen*/
  173.                 /*codiert abgelegt sind*/
  174.                 /*FirstAllEquas: Zeiger auf den ersten Puffer*/
  175.                 /*in dem alle Gleichung stehen*/
  176.                 /*OptEqua:  Puffer in dem eine Gleichung*/
  177.                 /*optimiert wird*/
  178.                 /*FileEquas:  Puffer in dem Gleichungen in*/
  179.                 /*String-Form (!) abgelegt werden, um daraus*/
  180.                 /*dann ein neues Source-File zu erstellen*/
  181.                 /*FirstOptEquas: Zeiger auf den ersten Puffer*/
  182.                 /*in dem die Gleichung optimiert wird*/
  183.  asmreadyflag2 = asmreadyflag;        /*die Variablen, die wichtig sind und*/
  184.  gal_type2     = gal_type;        /*in "AssembleInputFile" verändert*/
  185.  num_of_pins2  = num_of_pins;        /*werden, sichern*/
  186.  num_of_col2   = num_of_col;
  187.                     /*zum "Schein" assemblieren, dadurch spar*/
  188.  n = AssembleInputFile(OPTIMIZER);  /*ich mir den Syntax-Check, da das der*/
  189.                     /*Assembler jetzt macht*/
  190.  numofpins_Opt = num_of_pins;
  191.  asmreadyflag  = asmreadyflag2;        /*Variablen wieder herstellen*/
  192.  gal_type      = gal_type2;
  193.  num_of_pins   = num_of_pins2;
  194.  num_of_col    = num_of_col2;
  195.  
  196.  
  197.  if (!n) {
  198.    equastart = actptr;
  199.    if (!(FirstAllEquas = (struct Buffer *)AllocMem((long)sizeof(struct Buffer),MEMF_PUBLIC|MEMF_CLEAR))) {
  200.      FreeMem(fbuff, fsize);        /*Puffer für zu optimierendes File*/
  201.      ErrorReq(2);            /*kein Speicher mehr->Fehlermeldung*/
  202.      return(-1);
  203.     }
  204.  
  205.    AllEquas.ThisBuff = FirstAllEquas;
  206.    AllEquas.Entry    = (UBYTE *)(&FirstAllEquas->Entries[0]);
  207.    AllEquas.BuffEnd  = (UBYTE *)FirstAllEquas + (long)sizeof(struct Buffer);
  208.  
  209.    if (!TranslateEqua(&AllEquas)) {
  210.      equaend = actptr;            /*Zeiger auf DESCRIPTION merken*/ 
  211.  
  212.      if (!(FirstFileEquas = (struct Buffer *)AllocMem((long)sizeof(struct Buffer),MEMF_PUBLIC|MEMF_CLEAR))) {
  213.        FreeMem(fbuff, fsize);        /*Puffer für zu optimierendes File*/
  214.        FreeBuffer(FirstAllEquas);    /*Puffer für Gleichungen*/
  215.        ErrorReq(2);            /*kein Speicher mehr->Fehlermeldung*/
  216.        return(-1);
  217.       }
  218.      FileEquas.ThisBuff = FirstFileEquas;
  219.      FileEquas.Entry    = (UBYTE *)(&FirstFileEquas->Entries[0]);
  220.      FileEquas.BuffEnd  = (UBYTE *)FirstFileEquas + (long)sizeof(struct Buffer);
  221.  
  222.      if (AddByte(&FileEquas,0x0A)) {        /*vor den Gleichungen in*/
  223.        FreeMem(fbuff, fsize);            /*String-From noch einige*/
  224.        FreeBuffer(FirstAllEquas);        /*Returns einfügen*/
  225.        FreeBuffer(FirstFileEquas);
  226.        ErrorReq(2);
  227.        return(-1);
  228.       }
  229.      if (AddByte(&FileEquas,0x0A)) {
  230.        FreeMem(fbuff, fsize);
  231.        FreeBuffer(FirstAllEquas);
  232.        FreeBuffer(FirstFileEquas);
  233.        ErrorReq(2);
  234.        return(-1);
  235.       }
  236.  
  237.  
  238.  
  239.      OptWindow.Screen=screen;
  240.      if(!(optwin=(struct Window *)OpenWindow(&OptWindow))) {
  241.        FreeMem(fbuff, fsize);         /*Puffer für zu optimierendes File*/
  242.        FreeBuffer(FirstAllEquas);     /*Puffer für Gleichungen*/
  243.        FreeBuffer(FirstFileEquas);     /*Puffer Gleichungen in String-Form*/
  244.        ErrorReq(12);
  245.        return(-1);
  246.       }
  247.      orp = optwin->RPort;
  248.      DrawBorder(orp,&OBorder2a,18L,145L);
  249.      ClearMenuStrip(window);
  250.  
  251.      n    = 0;
  252.      AllEquas.ThisBuff = FirstAllEquas;
  253.      AllEquas.Entry    = (UBYTE *)(&FirstAllEquas->Entries[0]);
  254.      AllEquas.BuffEnd  = (UBYTE *)FirstAllEquas + (long)sizeof(struct Buffer);
  255.      equaflag = TRUE;            /*Gleichungen vorhanden*/
  256.  
  257.  
  258.  
  259.  
  260.      while (equaflag) {
  261.        SetAPen(orp,0L);
  262.        RectFill(orp,30L,23L,630L,142L);    /*Bildschirm löschen*/
  263.        SetAPen(orp,2L);
  264.  
  265.        oypos   = 20;            /*Variablen initialisieren*/
  266.        scrolls = 0;
  267.        reqflag = TRUE;
  268.  
  269.        PrintOptText((UBYTE *)"old equation:");
  270.        PrintEqua(AllEquas,NULL);
  271.  
  272.        Move(orp, 30L, 158L);
  273.        Text(orp, (UBYTE *)"Statistics:             ORs       ANDs", 38L);
  274.  
  275.        Move(orp, 30L, 170L);
  276.        Text(orp, (UBYTE *)"old equation:  ", 15L);
  277.        sprintf(&statstrng[0],"%4d",num_of_ORs);
  278.        Move(orp, 206L, 170L);
  279.        Text(orp, (UBYTE *)statstrng, 4L);
  280.        sprintf(&statstrng[0],"%4d",num_of_ANDs);
  281.        Move(orp, 294L, 170L);
  282.        Text(orp, (UBYTE *)statstrng, 4L);
  283.  
  284.        if (!(FirstOptEqua = (struct Buffer *)AllocMem((long)sizeof(struct Buffer),MEMF_PUBLIC|MEMF_CLEAR))) {
  285.      FreeMem(fbuff, fsize);        /*Puffer für zu optimierendes File*/
  286.          FreeBuffer(FirstAllEquas);    /*Puffer für Gleichungen*/
  287.          FreeBuffer(FirstFileEquas);   /*Puffer Gleichungen in String-Form*/
  288.      CloseWindow(optwin);
  289.          SetMenuStrip(window,&Menu1);
  290.      ErrorReq(2);            /*kein Speicher mehr->Fehlermeldung*/
  291.      return(-1);
  292.     }
  293.  
  294.        OptEqua.ThisBuff = FirstOptEqua;
  295.        OptEqua.Entry    = (UBYTE *)(&FirstOptEqua->Entries[0]);
  296.        OptEqua.BuffEnd  = (UBYTE *)FirstOptEqua + (long)sizeof(struct Buffer);
  297.  
  298.                 /*Gleichung in den Optimizer-Puffer kopieren*/
  299.        if (CopyEqua(AllEquas,OptEqua)) {
  300.      FreeMem(fbuff, fsize);        /*Puffer für zu optimierendes File*/
  301.          FreeBuffer(FirstAllEquas);    /*Puffer für Gleichungen*/
  302.          FreeBuffer(FirstOptEqua);    /*Puffer für Optimierer*/
  303.          FreeBuffer(FirstFileEquas);   /*Puffer Gleichungen in String-Form*/
  304.      CloseWindow(optwin);
  305.      ErrorReq(2);            /*kein Speicher mehr->Fehlermeldung*/
  306.          SetMenuStrip(window,&Menu1);
  307.      return(-1);
  308.     }
  309.  
  310.        Move(orp, 30L, 180L);
  311.        Text(orp, (UBYTE *)"optimized equation:  ", 21L);
  312.        sprintf(&statstrng[0],"   -");
  313.        Move(orp, 206L, 180L);
  314.        Text(orp, (UBYTE *)statstrng, 4L);
  315.        sprintf(&statstrng[0],"   -");
  316.        Move(orp, 294L, 180L);
  317.        Text(orp, (UBYTE *)statstrng, 4L);
  318.  
  319.                 /*versuche die Gleichung zu optimieren*/
  320.        SetWindowTitles(optwin, (UBYTE *)"please wait...(a few days - just a joke, I hope)", -1L);
  321.        if (OptimizeEqua(OptEqua)) {
  322.      FreeMem(fbuff, fsize);        /*Puffer für zu optimierendes File*/
  323.          FreeBuffer(FirstAllEquas);    /*Puffer für Gleichungen*/
  324.          FreeBuffer(FirstOptEqua);    /*Puffer für Optimierer*/
  325.          FreeBuffer(FirstFileEquas);   /*Puffer Gleichungen in String-Form*/
  326.      CloseWindow(optwin);
  327.      ErrorReq(2);            /*kein Speicher mehr->Fehlermeldung*/
  328.          SetMenuStrip(window,&Menu1);
  329.      return(-1);
  330.     }
  331.        SetWindowTitles(optwin, (UBYTE *)opttitle, -1L);
  332.  
  333.        PrintOptText((UBYTE *)"optimized equation:");
  334.        PrintEqua(OptEqua,NULL);
  335.  
  336.        Move(orp, 30L, 180L);
  337.        Text(orp, (UBYTE *)"optimized equation:  ", 21L);
  338.        sprintf(&statstrng[0],"%4d",num_of_ORs);
  339.        Move(orp, 206L, 180L);
  340.        Text(orp, (UBYTE *)statstrng, 4L);
  341.        sprintf(&statstrng[0],"%4d",num_of_ANDs);
  342.        Move(orp, 294L, 180L);
  343.        Text(orp, (UBYTE *)statstrng, 4L);
  344.  
  345.        n++;
  346.        sprintf(&OptTxt1[21],"%d",n);
  347.        strcat(&OptTxt1[0],(UBYTE *)":");
  348.        Move(orp,389L,156L);
  349.        Text(orp, &OptTxt1[0], (long)strlen(&OptTxt1[0]));
  350.  
  351.        for (;;) {
  352.          imsg = (struct IntuiMessage *)GetMsg(optwin->UserPort); 
  353.      if (!imsg)  WaitPort (optwin->UserPort);
  354.      else {
  355.        class = imsg->Class;
  356.        code  = imsg->Code;
  357.        if (class==GADGETUP) gadID=((struct Gadget *)imsg->IAddress)->GadgetID;
  358.        ReplyMsg(imsg);
  359.  
  360.        if (class == VANILLAKEY) {
  361.          if ((char)code == 'ü') {        /*Übernehmen*/
  362.            PrintEqua(OptEqua,&FileEquas);
  363.            break;
  364.           }
  365.          if (code == 'v') {            /*Verwerfen*/
  366.            PrintEqua(AllEquas,&FileEquas);
  367.            break;
  368.           }
  369.         }
  370.        if (class == GADGETUP) {
  371.          if (gadID == TAKEIT_GADID) {    /*Übernehmen*/
  372.            PrintEqua(OptEqua,&FileEquas);
  373.            break;
  374.           }
  375.          if (gadID == FORGETIT_GADID) {    /*Verwerfen*/
  376.            PrintEqua(AllEquas,&FileEquas);
  377.            break;
  378.           }
  379.         }
  380.           }
  381.         }
  382.  
  383.        FreeBuffer(FirstOptEqua);
  384.  
  385.        equaflag = GetNextEqua(&AllEquas);
  386.       }
  387.  
  388.  
  389.      CloseWindow(optwin);
  390.      SetMenuStrip(window,&Menu1);
  391.  
  392.                     /*neues Source-File erstellen*/
  393.      FileEquas.ThisBuff = FirstFileEquas;
  394.      FileEquas.Entry    = (UBYTE *)(&FirstFileEquas->Entries[0]);
  395.      FileEquas.BuffEnd  = (UBYTE *)FirstFileEquas + (long)sizeof(struct Buffer);
  396.  
  397.      if (MyFileReq((char *)"save new source file", (char *)".pld", YES)) {
  398.        PrintText((UBYTE *)"saving source file...",1);
  399.        if (WriteNewSource(FileEquas, equastart, equaend)) {
  400.      PrintText((UBYTE *)" Error!",0);
  401.          MyRequest(ERR_REQ, (UBYTE *)"write error!");
  402.     }
  403.        else
  404.      PrintText((UBYTE *)" o.k.",0);
  405.       }
  406.      FreeMem(fbuff, fsize);        /*Puffer für zu optimierendes File*/
  407.      FreeBuffer(FirstFileEquas);    /*Puffer Gleichungen in String-Form*/
  408.     }
  409.    FreeBuffer(FirstAllEquas);
  410.   }
  411.  return(0);
  412. }
  413.  
  414.  
  415.  
  416. /* GetProdTermStart: sucht den Anfang des Produktterms in den "pos" zeigt
  417.  
  418.    Aufruf   :    prodpos = GetProdTermStart(pos);
  419.    Parameter:   pos : ActBuffer-Struktur für Produktterm, dessen Anfang
  420.               gesucht werden soll
  421.    Ergebnis :   prodpos : ActBuffer-Struktur für den Produkttermanfang
  422.  
  423. */
  424. struct ActBuffer GetProdTermStart(pos)
  425. struct ActBuffer pos;
  426. {
  427.  
  428.  while(*pos.Entry) {
  429.    if (*pos.Entry == '+') {
  430.      IncPointer(&pos);
  431.      return(pos);
  432.     }
  433.    DecPointer(&pos);
  434.   }
  435.  
  436.  IncPointer(&pos);
  437.  return(pos);
  438.  
  439. }
  440.  
  441.  
  442.  
  443. /* KillProdTerm: löscht einen Produktterm "term" aus der Gleichung,
  444.          in dem der Term mit EQUASKIP überschrieben wird
  445.    Aufruf    : KillProdTerm(term);
  446.    Parameter : term: ActBuffer-Struktur für den Produktterm
  447.    Ergebnis  : ---
  448. */
  449. void KillProdTerm(term)
  450. struct    ActBuffer  term;
  451. {
  452. struct    ActBuffer  start;
  453.  
  454.  start = term;
  455.  while((*term.Entry) && (*term.Entry != '+')) {
  456.    *term.Entry = EQUASKIP;
  457.    IncPointer(&term);
  458.   }
  459.  
  460.  if (*term.Entry == '+')
  461.    *term.Entry = EQUASKIP;
  462.  
  463.  if (!*term.Entry) {
  464.    while((*start.Entry) && (*start.Entry != '+'))
  465.      DecPointer(&start);
  466.    if (*start.Entry == '+')
  467.      *start.Entry = EQUASKIP;
  468.   }
  469. }
  470.  
  471.  
  472.  
  473.  
  474. /* OptimizeEqua: Dies ist die eigentliche Routine, mit der die
  475.    Boolesche Gleichung vereinfacht wird.
  476.  
  477.    Aufruf   : result = OptimizeEqua(buff);
  478.  
  479.    Parameter: buff: ActBuffer-Struktur der zu optimierenden Gleichung
  480.    Ergebnis : result =  0:  alles o.k.
  481.              = -1:  Fehler: kein freier Speicher mehr
  482. */
  483. int OptimizeEqua(buff)
  484. struct    ActBuffer    buff;
  485. {
  486. struct    ActBuffer    optend, pos1, pos2, pos3, prodterm1, prodterm2;
  487. UBYTE    merker;
  488. int    varfound, prodfound, result;
  489.  
  490.  optend = buff;
  491.  while (*optend.Entry != EQUAEND)    /*Gleichungsende suchen*/
  492.    IncPointer (&optend);
  493.  *optend.Entry = 0;            /*Gleichungsende anstatt mit EQUAEND*/
  494.                     /*mit 0 kennzeichnen*/
  495.  
  496.                     /*Gleichungsanfang durch '0'*/
  497.                     /*kennzeichnen*/
  498.  IncPointer (&buff);            /*erster Eintrag ist Ausgangspin*/
  499.  if (!((*buff.Entry=='T')||(*buff.Entry=='R')||(*buff.Entry=='E')))
  500.    DecPointer (&buff);            /*.T, .R, .E berücksichtigen*/
  501.  merker = *buff.Entry;            /*Zeichen merken*/
  502.  *buff.Entry = 0;            /*Markierung setzen*/
  503.                     /*optend = Gleichungsende*/
  504.  IncPointer (&buff);            /*Zeiger auf erstes Zeichen*/
  505.  
  506.  if (!*buff.Entry) {            /*kein Zeichen da?*/
  507.    if (AddByte(&buff, numofpins_Opt/2))    /*GND eintragen*/
  508.      return(-1);            /*und Gleichungsende*/ 
  509.    *buff.Entry = EQUAEND;
  510.    DecPointer(&buff);
  511.    DecPointer(&buff);
  512.    *buff.Entry = merker;
  513.    return(0);                /*fertig*/
  514.   }   
  515.  
  516.  
  517.  if (result = Resolvente(buff, optend, buff)) {    /*Resolventen bilden*/
  518.    if (result == -1)                /*Fehler aufgetreten?*/
  519.      return(-1);                /*ja, dann Fehlercode*/
  520.    else {
  521.      if (AddByte(&buff, numofpins_Opt))        /*VCC eintragen*/
  522.        return(-1);                /*und Gleichungsende*/ 
  523.      *buff.Entry = EQUAEND;
  524.      DecPointer(&buff);
  525.      DecPointer(&buff);
  526.      *buff.Entry = merker;
  527.      return(0);                    /*fertig*/
  528.     }
  529.   }
  530.  
  531.  
  532.  optend = buff;
  533.  while (*optend.Entry)            /*Gleichungsende suchen*/
  534.    IncPointer(&optend);
  535.  
  536.         /*Absorptions-Gesetz anwenden: a + a * b <=> a */
  537.         /*Prinzip: Es wird der Produktterm "prodterm1" mit allen*/
  538.         /*andern ("prodterm2") verglichen und untersucht, ob einer*/
  539.         /*ein Teil von diesem ist. Wenn ja, wird der andere Produkt-*/
  540.         /*term gelöscht (mit EQUASKIP).*/
  541.  
  542.  pos1 = prodterm1 = buff;
  543.  
  544.  for (;;) {
  545.    pos2 = buff;
  546.    while (*pos2.Entry == EQUASKIP)    /*gelöschte Prod.terme*/
  547.      IncPointer(&pos2);            /*überspringen*/
  548.    for(;;) {
  549.      varfound = 0;
  550.      while (*prodterm1.Entry == EQUASKIP)    /*gelöschte Prod.terme*/
  551.        IncPointer(&prodterm1);            /*überspringen*/
  552.      while (*pos2.Entry) {            /*in der Gleichung nach der*/
  553.        if (*pos2.Entry == *prodterm1.Entry) {    /*Variable suchen, die als*/
  554.      varfound = 1;                /*erstes im Prod.term steht*/
  555.      break;
  556.     }
  557.        IncPointer(&pos2);
  558.       }
  559.      if (!varfound)            /*for-Schleife abbrechen, wenn*/
  560.        break;                /*keine entsprechende Variable*/
  561.                     /*gefunden wurde*/
  562.      prodterm2 = GetProdTermStart(pos2);    /*Prod.term-Anfang suchen*/
  563.      while (*prodterm2.Entry == EQUASKIP)    /*gelöschte Prod.terme*/
  564.        IncPointer(&prodterm2);            /*überspringen*/
  565.      if (prodterm1 != prodterm2) {
  566.        pos1 = prodterm1;        /*Prod.terme miteinander vergleichen*/
  567.        for (;;) {
  568.      pos2      = prodterm2;
  569.      prodfound = 0;
  570.      for (;;) {
  571.        if (*pos1.Entry == *pos2.Entry) {
  572.          prodfound = 1;
  573.          break;
  574.         }
  575.        IncPointer(&pos2);
  576.        if ((*pos2.Entry) && (*pos2.Entry != '+') && (*pos2.Entry != EQUASKIP))
  577.          IncPointer(&pos2);
  578.        else
  579.          break;
  580.       }
  581.      if (!prodfound)
  582.        break;
  583.      IncPointer(&pos1);
  584.      if ((*pos1.Entry) && (*pos1.Entry != '+') && (*pos1.Entry != EQUASKIP))
  585.        IncPointer(&pos1);
  586.      else
  587.        break;
  588.     }
  589.        if (prodfound)
  590.      KillProdTerm(prodterm2);
  591.       }
  592.      if (*pos2.Entry)
  593.        IncPointer(&pos2);
  594.     }
  595.  
  596.    while((*pos1.Entry != '+') && (*pos1.Entry))  /*nächsten Prod.term suchen*/
  597.      IncPointer(&pos1);
  598.    if (!*pos1.Entry)                /*kein Prod.term mehr da*/
  599.      break;                    /*dann fertig*/
  600.    IncPointer(&pos1);
  601.    prodterm1 = pos1;
  602.   }
  603.  
  604.  DecPointer(&buff);
  605.  *buff.Entry = merker;            /*Gleichung wieder herstellen*/
  606.  
  607.  if (AddByte(&optend, EQUAEND))        /*Gleichungsende wieder durch*/
  608.    return(-1);                /*EQUAEND markieren*/
  609.  if (AddByte(&optend, 0))
  610.    return(-1);
  611.  
  612.  return(0);
  613. }
  614.  
  615.  
  616.  
  617.  
  618. /* Resolvente:    hängt eine neue Schicht von Resolventen an die
  619.         zu optimierende Gleichung an
  620.  
  621.    Aufruf   :    result = Resolvente(optstart,optend,alteSchicht);
  622.  
  623.    Parameter:   optstart: ActBuffer-Struktur für Gleichungsanfang
  624.         optend  : ActBuffer-Struktur für Gleichungsende
  625.         alteSchicht: ActBuffer-Stuktur für vorherige Schicht
  626.    Ergebnis :    result =  0: alles o.k.
  627.                =  1: A + /A (VCC) gefunden=>Gleichung immer erfüllt
  628.                = -1: Fehler (kein freier Speicher mehr) 
  629. */
  630. int Resolvente(optstart, optend, alteSchicht)
  631. struct    ActBuffer    optstart, optend, alteSchicht;
  632. {
  633. struct    ActBuffer    pos1, pos2, neueSchicht;
  634. int    result, flag, resflag;        /*resflag: neue Resolvente*/
  635. UBYTE    var;                /*gefunden?*/
  636.                     /*neueSchicht: zeigt auf Stelle, an*/
  637.                     /*der weitere Resolventen angefügt*/
  638.                     /*werden können (Ende)*/
  639.  
  640.  if ((*alteSchicht.Entry == '+') || (*alteSchicht.Entry == '*'))
  641.    IncPointer(&alteSchicht);
  642.  resflag     = 0;            /*lokale Variablen initialisieren*/
  643.  pos1         = alteSchicht;
  644.  neueSchicht = optend;
  645.  
  646.  
  647.  for (;;) {
  648.    var  = *pos1.Entry;            /*Variable (Pinnummer) holen*/
  649.    if (var & NEGATION)            /*Variable negieren*/
  650.      var = var & (~NEGATION);
  651.    else
  652.      var = var | NEGATION;
  653.  
  654.    pos2 = optstart;            /*suche nach "/var"*/
  655.    for(;;) {
  656.       if (!SearchVar(&pos2,neueSchicht,var)) {
  657.     result = AddResolvente(pos1,pos2,optstart,&optend);
  658.     flag = 0;                  /*wenn die Variable ge-*/
  659.     while (pos2.Entry != neueSchicht.Entry) { /*funden wurde, wird pos2*/
  660.       if (*pos2.Entry == '+') {    /*auf den nächsten Produktterm ge-*/
  661.         flag = 1;            /*stellt. Wenn keiner da ist, bleibt*/
  662.         IncPointer(&pos2);        /*flag 0 und weiter unten erfolgt*/
  663.         break;            /*dann der Abbruch (if (!flag)..)*/
  664.        }
  665.       IncPointer (&pos2);
  666.      }
  667.         if (!result)
  668.           resflag = 1;
  669.         else {
  670.       if (result == 2)        /*A + /A gefunden? => Ausdruck wahr*/
  671.         return(1);            /*dann fertig*/
  672.       if (result == -1)
  673.         return(-1);
  674.      }
  675.         if (!flag)            /*kein Produktterm mehr da?*/
  676.       break;            /*dann Abbruch*/
  677.       }
  678.      else
  679.        break;
  680.   }
  681.  
  682.    IncPointer(&pos1);            /*Operator überspringen und pos1*/
  683.    if (pos1.Entry != neueSchicht.Entry) /*auf nächste Variable, falls nicht*/
  684.      IncPointer(&pos1);            /*bereits der neue Schichtanfang*/
  685.    else                    /*erreicht wurde, sonst Abbruch*/
  686.      break;
  687.  }
  688.  
  689.  
  690.  if (!resflag)                /*wurde neue Resolvente gefunden?*/
  691.    return(0);                /*nein, dann fertig*/
  692.  else {                    /*ja, dann Rekursion*/
  693.    return (Resolvente(optstart, optend, neueSchicht));
  694.   }
  695. }
  696.  
  697.  
  698.  
  699.  
  700. /* NumOfVar: gibt die Anzahl der Variablen im Produktterm zurück
  701.  
  702.    Aufruf   : vars = NumOfVar(term);
  703.    Parameter: term: ActBuffer-Struktur auf Produktterm-Anfang
  704.    Ergebnis : vars: Integer-Variable - enthält die Anzahl
  705. */
  706. int NumOfVar(term)
  707. struct    ActBuffer  term;
  708. {
  709. int    numofvar;
  710.  
  711.  numofvar = 0;
  712.  for (;;) {
  713.    numofvar++;
  714.    IncPointer(&term);
  715.    if (!*term.Entry || (*term.Entry == '+'))
  716.      break;
  717.    IncPointer(&term);
  718.   }
  719.  return(numofvar);
  720.  
  721. }
  722.  
  723.  
  724.  
  725.  
  726. /* AddResolvente: Fügt die beiden Produktterme in die "pos1" und "pos2"
  727.     zeigt zusammen, wobei die Variablen (Pinnummern) die unter "pos1"
  728.     und "pos2" stehen nicht berücksichtigt werden. Dann wird untersucht,
  729.     ob der neuentstandene Produktterm schon in der Gleichung steht.
  730.     Wenn nicht, wird der Produktterm an "equaend" angehängt.
  731.     Eine neue Resolvente ist geboren - welch' Dramatik.
  732.  
  733.    Aufruf:    result = AddResolvente(pos1,pos2,equastart,equaend);
  734.    Parameter:    pos1, pos2    : ActBuffer-Struktur
  735.         equastart    : ActBuffer-Struktur für Gleichungsanfang
  736.         equaend        : Zeiger(!) auf ActBuffer-Struktur
  737.         Parametererklärung siehe obigen Text
  738.    Ergebnis :    result =  0: es wurde eine Resolvente gebildet und angehängt
  739.                  equaend zeigt auf neues Ende
  740.                =  1: keine Resolvente
  741.                =  2: A + /A wurde gefunden (VCC -> fertig)
  742.                = -1: Fehler, kein Speicher
  743. */
  744. int AddResolvente(pos1, pos2, equastart, equaend)
  745. struct    ActBuffer  pos1, pos2, equastart, *equaend;
  746. {
  747. struct     ActBuffer  pos, res, res1, res2, prodterm, nextprodterm;
  748. int     n, i, numofvar, numofvar1, numofvar2;
  749. int     found;
  750. UBYTE     *termbuff, *term, entry;
  751.  
  752.  
  753.  res1 = GetProdTermStart(pos1);        /*ActBuffer-Struktur für den*/
  754.  res2 = GetProdTermStart(pos2);        /*jeweiligen Produkttermanfang holen*/
  755.  
  756.  if (res1 == res2)            /* "a * /a" weglassen */
  757.    return(1);
  758.  
  759.  numofvar1 = NumOfVar(res1);        /*Anzahl der benötigten Bytes*/
  760.  numofvar2 = NumOfVar(res2);        /*für die beiden Prod.terme holen*/
  761.  
  762.  if (!(termbuff = (UBYTE *)AllocMem((long)(numofvar1+numofvar2+1),MEMF_PUBLIC|MEMF_CLEAR)))
  763.    return(-1);
  764.  
  765.                     /*hier werden die beiden Produktterme*/
  766.  numofvar = numofvar1;            /*res1 und res2 zusammengehängt und*/
  767.  res      = res1;            /*in "termbuff" abgelegt (ohne '*'!)*/
  768.  pos      = pos1;
  769.  for (i=0; i<2; i++) {            /*zwei Produktterme*/
  770.    for (n=0; n<numofvar; n++) {
  771.      if (res.Entry != pos.Entry) {
  772.        term  = termbuff;        /*keine doppelten Pins zulassen*/
  773.        entry = *res.Entry;
  774.        found = 0;
  775.        while (*term) {
  776.      if (entry & NEGATION) {    /* "a * /a" nicht zulassen*/
  777.        if (*term == (entry & (~NEGATION))) {
  778.          FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  779.          return(1);
  780.         }
  781.       }
  782.      else {
  783.        if (*term == (entry | NEGATION)) {
  784.          FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  785.          return(1);
  786.         }
  787.       }
  788.      if (*term == entry)
  789.        found = 1;
  790.  
  791.      term++;
  792.     }
  793.  
  794.        if (!found)
  795.      *term = entry;
  796.       }
  797.      IncPointer(&res);
  798.      IncPointer(&res);
  799.     }
  800.    numofvar = numofvar2;
  801.    res      = res2;
  802.    pos        = pos2;
  803.   }
  804.  
  805.  if (!*termbuff)            /*wenn termbuff leer ist, dann*/
  806.    *termbuff = numofpins_Opt;        /*war A+/A in der Gleichung => VCC*/
  807.                 /*untersuchen, ob der neue Prod.term*/
  808.                 /*"termbuff"  schon existiert*/
  809.  pos   = equastart;
  810.  found = 0;
  811.  for(;;) {
  812.    prodterm = pos;
  813.    while ((*pos.Entry != '+') && (entry = *pos.Entry)) {
  814.      term  = termbuff;
  815.      found = 0;
  816.      while (*term) {
  817.        if (*term == entry) {
  818.      found = 1;
  819.      break;
  820.     }
  821.        term++;
  822.       }
  823.      if (!found)
  824.        break;
  825.      IncPointer(&pos);
  826.      if (*pos.Entry == '*')        /*'*' überspringen, falls vorhanden*/
  827.        IncPointer(&pos);
  828.     }
  829.  
  830.  
  831.    while ((*pos.Entry != '+') && (*pos.Entry))    /*nächsten Prod.term suchen*/
  832.      IncPointer(&pos);
  833.  
  834.    nextprodterm = pos;
  835.  
  836.    if (found) {
  837.      term = termbuff;
  838.      while (*term) {
  839.        pos   = prodterm;
  840.        found = 0;
  841.        while ((*pos.Entry != '+') && (entry = *pos.Entry)) {
  842.      if (entry == *term) {
  843.        found = 1;
  844.        break;
  845.       }
  846.          IncPointer(&pos);
  847.      if (*pos.Entry == '*')
  848.        IncPointer(&pos);
  849.         }
  850.        if (!found)
  851.      break;
  852.        term++;
  853.       }
  854.     }
  855.    if (found)
  856.      break;                /*for-Schleife verlassen*/
  857.  
  858.    pos = nextprodterm;
  859.    if (!*pos.Entry)
  860.      break;
  861.  
  862.    IncPointer(&pos);
  863.   }
  864.  
  865.  
  866.  if (!found) {                /*existiert Prod.term schon ?*/
  867.    if (AddByte(equaend,'+')) {        /*nein, dann an Gleichung anhängen*/
  868.      FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  869.      return(-1);
  870.     }
  871.    term = termbuff;
  872.    while (*term) {
  873.      if (AddByte(equaend,*term)) {
  874.        FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  875.        return(-1);
  876.       }
  877.      if (AddByte(equaend,'*')) {
  878.        FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  879.        return(-1);
  880.       }
  881.      term++;
  882.     }
  883.    DecPointer(equaend);
  884.    *equaend->Entry = 0;                /*Endmarkierung*/
  885.    entry = *termbuff;
  886.    FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  887.    if (entry == numofpins_Opt)            /*wenn VCC gefunden wurde,*/
  888.      return(2);                    /*dann 2 zurückgeben*/
  889.    else
  890.      return(0);
  891.   }
  892.  
  893.  FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  894.  return(1);
  895. }
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904. /* SearchVar: suche ab "pos" den Pin "var" bis nach "end"
  905.           Die Pinnummern werden jetzt als Variablen bezeichnet, da
  906.           sie ab jetzt wie Boolesche Variablen behandelt werden.
  907.    Aufruf   : result = SearchVar(pos,end,var);
  908.  
  909.    Parameter: pos : Zeiger auf ActBuffer-Struktur - Startposition ab
  910.             der gesucht werden soll
  911.           end : ActBuffer-Stuktur für Ende
  912.           var : Variable nach der gesucht werden soll
  913.    Ergebnis : result =  0: gefunden, pos zeigt auf Zeichen
  914.              = -1: nicht gefunden
  915. */
  916. int SearchVar(pos, end, var)
  917. register struct    ActBuffer  *pos, end;
  918. register UBYTE    var;
  919. {
  920.  
  921.  while (pos->Entry != end.Entry) {    /*bis zum Ende suchen*/
  922.    if (*pos->Entry == var)
  923.      return(0);
  924.    IncPointer(pos);
  925.   }
  926.  return(-1);
  927.  
  928. }
  929.  
  930.  
  931.  
  932.  
  933.  
  934.  
  935.  
  936. /* WriteNewSource: Erstellt aus dem alten Source-File und der Liste der
  937.            neuen Gleichungen (optimiert) ein neues Source-File.
  938.            Dabei werden die Gleichungen aus dem alten Source-File
  939.            durch die neuen ersetzt.
  940.   Aufruf:   result = WriteNewSource(buff, equastart, equaend);
  941.   Parameter: file:  ActBuffer-Struktur für Liste der Gleichungen
  942.             in String-Form
  943.          equastart: Zeiger auf die Stelle im original Source-File,
  944.             an der die Gleichungen beginnen
  945.          equaend  : Zeiger auf die Stelle im original Source-File,
  946.             an der die Gleichungen enden (DESCRIPTION)
  947.   Ergebnis : result =  0: alles o.k.
  948.             = -1: Fehler beim Schreiben
  949. */
  950. int WriteNewSource(buff, equastart, equaend)
  951. struct    ActBuffer    buff;
  952. UBYTE    *equastart, *equaend;
  953. {
  954. long    result;
  955. struct    FileHandle    *fh;
  956. UBYTE    *filebuffer, *filebuffer2;
  957.  
  958.  
  959.  if ((fh = Open(&path[0], MODE_NEWFILE))) {
  960.                     /*Header des Source-Files schreiben*/
  961.    result = Write(fh, fbuff, (long)(equastart-fbuff));
  962.    if (result == -1L) {                /*Fehler beim Schreiben?*/
  963.      Close(fh);                    /*ja, dann Ende*/
  964.      return(-1);
  965.     }
  966.                     /*Gleichungen schreiben*/
  967.    for (;;) {
  968.      filebuffer = filebuffer2 = buff.Entry;
  969.  
  970.      while (filebuffer2 < buff.BuffEnd) {    /*Größe des Puffers bestimmen*/
  971.        if (!*filebuffer2) 
  972.      break;
  973.        filebuffer2++;
  974.       }
  975.  
  976.      result = Write(fh, filebuffer, (long)(filebuffer2-filebuffer));
  977.      if (result == -1L) {            /*Fehler beim Schreiben?*/
  978.        Close(fh);                /*ja, dann Ende*/
  979.        return(-1);
  980.       }
  981.  
  982.      if (!buff.ThisBuff->Next)            /*noch ein Puffer da?*/
  983.        break;                    /*nein, dann for(;;)-Ende*/
  984.      buff.ThisBuff = buff.ThisBuff->Next;
  985.      buff.Entry    = (UBYTE *)(&buff.ThisBuff->Entries[0]);
  986.      buff.BuffEnd  = (UBYTE *)buff.ThisBuff + (long)sizeof(struct Buffer);
  987.     }
  988.  
  989.                     /*Teil ab DESCRIPTION schreiben*/
  990.    result = Write(fh, equaend, (long)(fbuff+fsize-equaend));
  991.    if (result == -1L) {                /*Fehler beim Schreiben?*/
  992.      Close(fh);                    /*ja, dann Ende*/
  993.      return(-1);
  994.     }
  995.  
  996.    Close(fh);
  997.   }
  998.  else
  999.    return(-1);
  1000.  
  1001.  return(0);
  1002. }
  1003.  
  1004.  
  1005.  
  1006.  
  1007.  
  1008. /* CopyEqua:  Kopiert eine Gleichung aus dem Puffer from_buff in den
  1009.           Puffer to_buff. Dabei werden unsinnige Konstruktionen
  1010.           wie  A*A*B*A, A * /A * B bereits voroptimiert.
  1011.    Aufruf  :  result = CopyEqua(from_buff, to_buff);
  1012.    Paramter:  from_buff: ActBuffer-Struktur der Quelle (kein Zeiger!!!)
  1013.           to_buff  : ActBuffer-Struktur des Ziels  (kein Zeiger!!!)
  1014.    Ergebnis:  0: alles o.k.     sonst: Fehler (kein Speicher)
  1015. */
  1016. int CopyEqua(from_buff, to_buff)
  1017. struct    ActBuffer    from_buff, to_buff;
  1018. {
  1019. struct     ActBuffer    equastart, prodtermstart, pos;
  1020. UBYTE     entry, pins[2*24];
  1021. register int    n;
  1022.  
  1023.  
  1024.  if (AddByte(&to_buff, *from_buff.Entry))    /*Ausganspin kopieren*/
  1025.    return(-1);
  1026.  
  1027.  IncPointer(&from_buff);
  1028.  entry = *from_buff.Entry;
  1029.  if ((entry == 'T') || (entry == 'R') || (entry == 'E')) {
  1030.    if (AddByte(&to_buff, entry))        /*T,R,E kopieren*/
  1031.      return(-1);
  1032.    IncPointer(&from_buff);
  1033.   }
  1034.  
  1035.                         /*Gleichung kopieren*/
  1036.  equastart = prodtermstart = to_buff;
  1037.  for (;;) {
  1038.    for (n=0; n<2*24; pins[n++]=0);
  1039.  
  1040.    for (;;) {
  1041.      entry = *from_buff.Entry;
  1042.  
  1043.      if (entry & NEGATION) {
  1044.        if (pins[(entry&~NEGATION)-1]) {        /* A * /A ? */
  1045.      pos = prodtermstart;            /*ja, dann Term im to_buff*/
  1046.      while (pos.Entry != to_buff.Entry) {    /*löschen und im from_buff*/
  1047.        *pos.Entry = EQUASKIP;        /*überspringen*/
  1048.        IncPointer(&pos);
  1049.       }
  1050.      to_buff = prodtermstart;
  1051.      while ((*from_buff.Entry != '+') && (*from_buff.Entry != EQUAEND))
  1052.        IncPointer(&from_buff);
  1053.      DecPointer(&from_buff);
  1054.     }
  1055.        else {
  1056.      if (!pins[(entry&~NEGATION)-1+24]) {    /*Pin mehrmals im Produktterm?*/
  1057.        pins[(entry&~NEGATION)-1+24] = 1;    /*nein, dann kopieren*/
  1058.         if (AddByte(&to_buff, entry))    /*Pinnummer kopieren*/
  1059.          return(-1);
  1060.       }
  1061.     }
  1062.       }
  1063.      else {
  1064.        if (pins[entry-1+24]) {            /* A * /A ? */
  1065.      pos = prodtermstart;            /*ja, dann Term im to_buff*/
  1066.      while (pos.Entry != to_buff.Entry) {    /*löschen und im from_buff*/
  1067.        *pos.Entry = EQUASKIP;        /*überspringen*/
  1068.        IncPointer(&pos);
  1069.       }
  1070.      to_buff = prodtermstart;
  1071.      while ((*from_buff.Entry != '+') && (*from_buff.Entry != EQUAEND))
  1072.        IncPointer(&from_buff);
  1073.      DecPointer(&from_buff);
  1074.     }
  1075.        else {
  1076.      if (!pins[entry-1]) {            /*Pin mehrmals im Produktterm?*/
  1077.        pins[entry-1] = 1;            /*nein, dann kopieren*/
  1078.         if (AddByte(&to_buff, entry))    /*Pinnummer kopieren*/
  1079.          return(-1);
  1080.       }
  1081.     }
  1082.       }
  1083.  
  1084.  
  1085.      IncPointer(&from_buff);            /*Zeiger auf Operator oder */
  1086.      entry = *from_buff.Entry;            /*EQUAEND und in to_buff*/
  1087.  
  1088.      if (entry == EQUAEND) {            /*Ende erreicht?*/
  1089.        DecPointer(&to_buff);            /*ja, dann fertig*/
  1090.        if (!((*to_buff.Entry == '+') || (*to_buff.Entry == '*')))
  1091.      IncPointer(&to_buff);            /* +,* am Ende wegmachen*/
  1092.        if (AddByte(&to_buff, EQUAEND))        /*Endmarkierung setzen*/
  1093.      return(-1);
  1094.        return(0);
  1095.       }
  1096.  
  1097.      if (to_buff.Entry != equastart.Entry) {    /*noch am Anfang?*/
  1098.        DecPointer(&to_buff);
  1099.        if (*to_buff.Entry != '+') {
  1100.      if (*to_buff.Entry != '*') {
  1101.        IncPointer(&to_buff);
  1102.        if (AddByte(&to_buff, entry))
  1103.          return(-1);
  1104.       }
  1105.      else {
  1106.        if (entry == '+')
  1107.          *to_buff.Entry = '+';
  1108.        IncPointer(&to_buff);
  1109.       }
  1110.     }
  1111.        else
  1112.      IncPointer(&to_buff);
  1113.       }
  1114.  
  1115.  
  1116.      if (entry == '+')                /*Produkttermende?*/
  1117.        break;                    /*for-Schleife verlassen*/
  1118.  
  1119.  
  1120.      IncPointer(&from_buff);            /*Zeiger auf Pinnamen*/
  1121.     }
  1122.  
  1123.    prodtermstart = to_buff;
  1124.  
  1125.    IncPointer(&from_buff);
  1126.   }
  1127.  
  1128. }
  1129.  
  1130.  
  1131.  
  1132.  
  1133. /* PrintEqua:  gibt eine Gleichung die mit ENDEQUAS oder ENDEQUA
  1134.            abgeschlossen ist, auf dem Bildschirm aus
  1135.    Aufruf:     result = PrintEqua(buff,flag);
  1136.    Parameter:  buff: ActBuffer-Struktur (kein Zeiger!!!)
  1137.            filebuff = 0: Ausgabe auf Bildschrim
  1138.                 = Zeiger auf ActBuffer-Struktur: Ausgabe in eine
  1139.               verkettet List aus der dann später das neue
  1140.               Source-File entsteht
  1141.    Ergebnis :  result = 0: alles o.k.    sonst: Fehler (kein Speicher)
  1142.            num_of_ORs, num_of_ANDs: enthält die Anzahl der vor-
  1143.                     gekommenen '+' und '*'
  1144. */
  1145. int PrintEqua(buff, filebuff)
  1146. struct    ActBuffer    buff, *filebuff;
  1147. {
  1148. char    estrng[SIZE_OF_EQUASTRING];
  1149. int    n, entry, xoffset, notready;
  1150.  
  1151.  
  1152.  num_of_ORs = num_of_ANDs = 0;
  1153.  estrng[0] = 0;                    /*String löschen*/
  1154.  
  1155.  entry = *buff.Entry;
  1156.  
  1157.  if (entry & NEGATION) {
  1158.    strcat(&estrng[0], (UBYTE *)"/");
  1159.    entry = entry & (~NEGATION);
  1160.   }
  1161.  if (PinNamesOpt[entry-1][0] == '/')
  1162.    strcat (&estrng[0], &PinNamesOpt[entry-1][1]);    /*Ausgang*/
  1163.  else
  1164.    strcat (&estrng[0], &PinNamesOpt[entry-1][0]);
  1165.  
  1166.  entry = GetNext(&buff);
  1167.  
  1168.  if (entry == 'T') {
  1169.    entry = GetNext(&buff);
  1170.    strcat (&estrng[0], (UBYTE *)".T");        /*Typ des Ausgangs*/
  1171.   }
  1172.  else
  1173.    if (entry == 'E') {
  1174.      entry = GetNext(&buff);
  1175.      strcat (&estrng[0], (UBYTE *)".E");
  1176.     }
  1177.    else
  1178.      if (entry == 'R') {
  1179.        entry = GetNext(&buff);
  1180.        strcat (&estrng[0], (UBYTE *)".R");
  1181.       }
  1182.  
  1183.  strcat (&estrng[0], (UBYTE *)" = ");        /*'='-Zeichen*/
  1184.  
  1185.  xoffset = strlen(&estrng[0]);            /*Stringlänge merken*/
  1186.  
  1187.  notready = TRUE;
  1188.  while (notready) {
  1189.    while (strlen(&estrng[0]) < (SIZE_OF_EQUASTRING - 15)) {
  1190.  
  1191.      if (entry & NEGATION) {
  1192.        strcat(&estrng[0], (UBYTE *)"/");
  1193.        entry = entry & (~NEGATION);
  1194.       }
  1195.      if (PinNamesOpt[entry-1][0] == '/')        /*Pinnamen holen*/
  1196.        strcat (&estrng[0], &PinNamesOpt[entry-1][1]);
  1197.      else
  1198.        strcat (&estrng[0], &PinNamesOpt[entry-1][0]);
  1199.  
  1200.      if ((entry = GetNext(&buff)) == EQUAEND) {
  1201.        notready = FALSE;
  1202.        break;
  1203.       }
  1204.  
  1205.      if (entry == '+') {
  1206.        strcat(&estrng[0], (UBYTE *)" + ");    /*Operator holen*/
  1207.        num_of_ORs++;
  1208.       }
  1209.      else {
  1210.        strcat(&estrng[0], (UBYTE *)"*");
  1211.        num_of_ANDs++;
  1212.       }
  1213.  
  1214.      if ((entry = GetNext(&buff)) == EQUAEND) {
  1215.        notready = FALSE;
  1216.        break;
  1217.       }
  1218.  
  1219.     }
  1220.  
  1221.    if (!filebuff)
  1222.      PrintOptText(&estrng[0]);            /*eine Zeile ausgeben*/
  1223.    else {
  1224.      n = 0;                /*String in Liste schreiben*/
  1225.      while (estrng[n]) {
  1226.        if (AddByte(filebuff,estrng[n]))        /*Zeichen in Liste schreiben*/
  1227.          return(-1);
  1228.        n++;
  1229.       }
  1230.      if (AddByte(filebuff,0x0A))        /*Return eintragen*/
  1231.        return(-1);
  1232.     }
  1233.  
  1234.    for (n=0; n<xoffset; n++)            /*bis zu xoffset mit ' '*/
  1235.      estrng[n] = ' ';                /*füllen*/
  1236.    estrng[xoffset] = 0;                /*Rest vom String löschen*/
  1237.   }
  1238.  
  1239.  if (filebuff)                    /*File-Liste erzeugen?*/
  1240.    if (AddByte(filebuff,0x0A))            /*nach einer Gleichung*/
  1241.      return(-1);                /*noch ein Return eintragen*/
  1242.  
  1243.  return(0);
  1244. }
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253. /* GetNext: holt den nächsten gültigen! Eintrag aus dem Puffer mit
  1254.         der Struktur buff
  1255.    Aufruf:  entry = GetNext(buff);
  1256.    Parameter: buff: Zeiger auf ActBuffer-Struktur
  1257.    Ergebnis : entry: nächter Eintrag, der kein EQUASKIP ist
  1258. */
  1259. int GetNext(buff)
  1260. struct    ActBuffer  *buff;
  1261. {
  1262.  do
  1263.    IncPointer(buff);
  1264.  while (*buff->Entry == EQUASKIP);
  1265.  
  1266.  return(*buff->Entry);
  1267. }
  1268.  
  1269.  
  1270.  
  1271.  
  1272. /*GetNextEqua : Sucht innerhalb des Puffers in dem die gesamten Gleichung
  1273.         codiert abgelegt sind, nach der nächsten Gleichung
  1274.  
  1275.   Aufruf:     result = GetNextEqua(buff);
  1276.   Parameter:  buff :  Zeiger auf ActBuffer-Stuktur
  1277.   Ergebnis :  FALSE :  keine Gleichung mehr im Puffer
  1278.           TRUE  :  noch mindestens eine Gleichung im Puffer
  1279.           buff  :  Zeiger auf ActBuffer-Struktur, entsprechend gefüllt
  1280. */
  1281. int GetNextEqua(buff)
  1282. struct    ActBuffer    *buff;
  1283. {
  1284.  
  1285.  while (*buff->Entry != EQUAEND)
  1286.    IncPointer(buff);
  1287.  
  1288.  IncPointer(buff);
  1289.  
  1290.  if (*buff->Entry == EQUASEND)
  1291.    return(FALSE);
  1292.  else
  1293.    return(TRUE);
  1294.  
  1295. }
  1296.  
  1297.  
  1298.  
  1299.  
  1300.  
  1301.  
  1302. /* PrintOptText :  gibt einen Text im Optimizer-Window aus
  1303.           es wird automatisch gescrollt, wenn der Platz nicht
  1304.           mehr ausreicht
  1305.    Parameter:  txt: Zeiger auf String
  1306.            globale Variablen: oypos: y-Pos. an der der Text ausgegben
  1307.                      werden soll
  1308.    Ergebnis : ---
  1309. */
  1310. void PrintOptText(txt)
  1311. UBYTE    *txt;
  1312. {
  1313.  if (oypos<140)
  1314.    oypos += 10;
  1315.  else {
  1316.    if (reqflag) {
  1317.      ScrollRequester();
  1318.      reqflag = FALSE;
  1319.     }
  1320.    scrolls++;
  1321.    ScrollRaster(orp,0L,10L,30L,23L,630L,142L);
  1322.   }
  1323.  Move(orp,30L,(long)oypos);
  1324.  Text(orp,txt,(long)strlen(txt));
  1325.  
  1326.  if (scrolls == 11) {
  1327.    scrolls = 1;
  1328.    ScrollRequester();
  1329.   }
  1330. }
  1331.  
  1332.  
  1333.  
  1334.  
  1335.  
  1336. /*ScrollRequester :   öffnet einen Requester und wartet auf Tastendruck
  1337.               oder auf Anklicken des "Weiter"-Gadgets
  1338.   Parameter: keine
  1339.   Ergebnis : -1: Requester konnte nicht geöffnet werden
  1340.           0: weiter
  1341. */
  1342. int ScrollRequester()
  1343. {
  1344. struct    IntuiMessage    *imsg;
  1345. ULONG    class;
  1346.  
  1347.  if (Request(&ScrollReq,optwin)) {
  1348.    for (;;) {
  1349.      imsg = (struct IntuiMessage *)GetMsg(optwin->UserPort); 
  1350.      if (!imsg) WaitPort (optwin->UserPort);
  1351.      else {
  1352.        class = imsg->Class;
  1353.        ReplyMsg(imsg);
  1354.        if (class == VANILLAKEY) {
  1355.          EndRequest(&ScrollReq,optwin);
  1356.          return(0);
  1357.         }
  1358.        if (class == GADGETUP) {
  1359.          EndRequest(&ScrollReq,optwin);
  1360.          return(0);
  1361.        }
  1362.       }
  1363.     }
  1364.   }
  1365.  else  return(-1);
  1366. }
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372. /* TranslateEqua:
  1373.           Übersetzt die Booleschen Gleichungen aus der String-Form
  1374.           in eine codierte Form, so daß sie durch den Optimizer
  1375.           leichter bearbeitet werden können.
  1376.           Codierung: Pinname     ->  Pinnummer
  1377.                    /Pinname    ->  Pinnummer mit gesetztem Bit 7
  1378.              T,R,E,+,*  ->  T,R,E,+,* 
  1379.             CR,LF,'.','=' werden weggelassen
  1380.  
  1381.    Aufruf   : result = TransLateEqua(buff)
  1382.    Parameter: buff : Zeiger auf ActBuffer-Struktur
  1383.    Ergebnis:  0: alles o.k.    sonst: Fehler
  1384.           actptr: Zeiger auf Ende der Gleichungen
  1385. */
  1386. int TranslateEqua(buff)
  1387. struct    ActBuffer    *buff;
  1388. {
  1389. UBYTE    chr, entry;
  1390.  
  1391.  if (GetNextChar()) {            /*Dateiende?*/
  1392.    AsmError(2);                /*ja, dann Fehler*/
  1393.    return(-1);
  1394.   }
  1395.                         /*Gleichungen vorhanden?*/
  1396.  if (!strncmp(actptr,(UBYTE *)"DESCRIPTION",11)) {
  1397.    AsmError(33);                /*nein, dann Fehlermeldung*/
  1398.    return(-1);
  1399.   }
  1400.  
  1401.  for (;;) {
  1402.    IsPinName(&PinNamesOpt[0], numofpins_Opt);
  1403.    if (!actPin.p_Pin) {            /*Pinname?*/
  1404.      AsmError(11);            /*nein, dann Fehler*/
  1405.      return(-1);
  1406.     }
  1407.  
  1408.    if (actPin.p_Neg)
  1409.      entry = actPin.p_Pin | NEGATION;
  1410.    else
  1411.      entry = actPin.p_Pin;
  1412.    if (AddByte(buff,entry))
  1413.      return(-1);
  1414.  
  1415.    if (*actptr == '.') {
  1416.      actptr++;
  1417.      chr = *actptr++;
  1418.      if (!((chr == 'T') || (chr == 'E') || (chr == 'R'))) {
  1419.        AsmError(13);
  1420.        return(-1);
  1421.       }         
  1422.      if (AddByte(buff,chr))
  1423.        return(-1);
  1424.     }
  1425.  
  1426.   if (GetNextChar()) {            /*Dateiende?*/
  1427.      AsmError(2);            /*ja, dann Fehler*/
  1428.      return(-1);
  1429.     }
  1430.  
  1431.    if (*actptr != '=') {        /* '=' ?*/
  1432.      AsmError(14);            /*nein, dann Fehler*/
  1433.      return(-1);
  1434.     }         
  1435.  
  1436.    actptr++;
  1437.  
  1438.    if (GetNextChar()) {            /*Dateiende?*/
  1439.      AsmError(2);            /*ja, dann Fehler*/
  1440.      return(-1);
  1441.     }
  1442.  
  1443.    for (;;) {
  1444.      IsPinName(&PinNamesOpt[0], numofpins_Opt);
  1445.      if (!actPin.p_Pin) {        /*Pinname?*/
  1446.        AsmError(11);            /*nein, dann Fehler*/
  1447.        return(-1);
  1448.       }
  1449.  
  1450.      if (actPin.p_Neg)
  1451.        entry = actPin.p_Pin | NEGATION;
  1452.      else
  1453.        entry = actPin.p_Pin;
  1454.      if (AddByte(buff,entry))
  1455.        return(-1);
  1456.  
  1457.      if (GetNextChar()) {        /*Dateiende?*/
  1458.        AsmError(2);            /*ja, dann Fehler*/
  1459.        return(-1);
  1460.       }
  1461.  
  1462.      if (!((*actptr == '+') || (*actptr == '*'))) {       /*'+' oder '*'?*/
  1463.        if (strncmp(actptr,(UBYTE *)"DESCRIPTION",11)) {   /*DESCRIPTION? */
  1464.      if (AddByte(buff,EQUAEND))      /*Markierung für das Ende einer*/
  1465.        return(-1);            /*Gleichung*/
  1466.          break;            /*nein, dann innere Endlosschleife beenden*/
  1467.     }
  1468.        else {
  1469.      if (AddByte(buff,EQUAEND))      /*Markierung für das Ende einer*/
  1470.        return(-1);            /*Gleichung*/
  1471.      if (AddByte(buff,EQUASEND))    /*Markierung für das Ende aller*/
  1472.        return(-1);            /*Gleichungen (danach kommt DESCRIPTION)*/
  1473.      return(0);            /*alle Gleichungen übersetzt - Ende*/
  1474.     }
  1475.       }
  1476.  
  1477.      if (AddByte(buff,*actptr))
  1478.        return(-1);
  1479.  
  1480.      actptr++;
  1481.  
  1482.      if (GetNextChar()) {        /*vorzeitiges Dateiende?*/
  1483.        AsmError(2);            /*ja, dann Fehler*/
  1484.        return(-1);
  1485.       }
  1486.     }
  1487.   }
  1488. }
  1489.  
  1490.  
  1491.  
  1492.  
  1493.